package com.nxn.core.web.action.base;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.nxn.core.service.CRUDService;
import com.nxn.core.utils.reflection.ReflectionUtils;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;

public abstract class CRUDAction<T, PK extends Serializable> extends BaseAction implements ModelDriven<T>, Preparable{
	private static final long serialVersionUID = -172930664357126487L;

	/** 进行增删改操作后,以redirect方式重新打开action默认页的result名. */
	public static final String RELOAD = "reload";
	public static final String VIEW = "view";

	/** 实体对象列表 */
	protected List<T> entityList = Collections.<T>emptyList();

	/** 实体对象 */
	protected T entity;
	/** 实体对象 */
	protected Class<T> entityClass;
	/** 实体类主键 */
//	protected PK id;
	/** 实体类的名字 */
	protected String entityClassName = "";
	
	@Autowired(required=true)
	public CRUDService<T, PK> crudService;
	
	@SuppressWarnings("unchecked")
	public CRUDAction() {
		entityClass = ReflectionUtils.getSuperClassGenricType(getClass(), 0);
	}
	
	/**
	 * 根据泛型类型实例化对象
	 * 
	 * @return 泛型类型的对象
	 * @throws Exception
	 */
	public T instanceEntityObject() throws Exception {
		try {
			return entityClass.newInstance();
		} catch (Exception e) {
			logger.error("CRUDAction的泛型类型实例化失败! 错误信息: {}", e.getMessage());
			throw e;
		} 
	}
	
	/**
	 * Action函数, 默认的action函数, 默认调用list()函数.
	 */
	@Override
	public String execute() throws Exception {
		return list();
	}

	// -- CRUD Action函数 --//
	/**
	 * Action函数,显示Entity列表界面. 建议return SUCCESS.
	 */
	public String list() throws Exception {
		try{
			this.entityList = crudService.getAll(entityClass);
		} catch(Exception e){
			logger.error("读取实体类[{}]列表失败! 错误原因: {}", this.entityClass, e.getMessage());
		}
		
		return SUCCESS;
	}

	/**
	 * Action函数,显示Entity界面. 建议return VIEW.
	 */
    public String view() throws Exception {
		// prepare已经完成此功能
		// 使用getModel()获得实体类
		logger.info("成功读取实体对象[{}]", this.entityClassName);
		
    	return VIEW;
    }
	
	/**
	 * Action函数,显示新增或修改Entity界面. 建议return INPUT.
	 */
	@Override
	public String input() throws Exception {
		// prepare已经完成此功能
		// 使用getModel()获得实体类
		logger.info("成功读取实体对象[{}]", this.entityClassName);
		
		return INPUT;
	}

	/**
	 * Action函数,新增或修改Entity. 建议return RELOAD.
	 */
	public String save() throws Exception {
		try {
			crudService.save(entity);
		} catch (Exception e) {
			logger.error("更新实体对象[{}]失败! 错误原因  : {}", this.entityClassName, e.getMessage());
		}
		logger.info("成功更新实体对象[{}]", this.entityClassName);
		
		return RELOAD;
	}

	/**
	 * Action函数,删除Entity. 建议return RELOAD.
	 */
	@SuppressWarnings("unchecked")
	public String delete() throws Exception {
		try {
			long id = getParameterForLong("id");
			crudService.remove(crudService.get(entityClass, (PK)Long.valueOf(id)));
		} catch (Exception e) {
			logger.error("删除实体对象[{}]失败! 错误原因  : {}", this.entityClass, e.getMessage());
		}
		logger.info("成功删除实体对象[{}]", this.entityClass);
		
		return RELOAD;
	}

	// -- Preparable函数 --//
	/**
	 * 实现空的prepare()函数,屏蔽所有Action函数公共的二次绑定.
	 */
	public void prepare() throws Exception {
	}

	/**
	 * 在input()前执行二次绑定.
	 */
	public void prepareInput() throws Exception {
		prepareModel();
	}
	/**
	 * 在view()前执行二次绑定.
	 */
    public void prepareView() throws Exception {
        prepareModel();
    }
	/**
	 * 在save()前执行二次绑定.
	 */
	public void prepareSave() throws Exception {
		prepareModel();
	}

	/**
	 * 等同于prepare()的内部函数,供prepardMethodName()函数调用.
	 */
	protected void prepareModel() throws Exception {
		// 利用反射新建enity对象
		this.entity = this.instanceEntityObject();
		this.entityClassName = this.entity.getClass().getSimpleName();
		
		long id = getParameterForLong("id");
		if(id != 0) {
			try {
//				this.id = (PK) Long.valueOf(id);
//				T dataEntity = getServiceImpl().get(this.id);
				T dataEntity = crudService.get(entityClass, (PK)Long.valueOf(id));
				if(dataEntity != null) {
					this.entity = dataEntity;
				}
			} catch(NumberFormatException e) {
				logger.error("实体对象对象[{}]的id:{}转换数字失败!", this.entityClassName, id);
			} catch (Exception e) {
				logger.error("读取实体对象[{}]失败! id: {}, 错误原因 : {}",new Object[]{
						this.entityClassName,
						id,
						e.getMessage()
				});
				
				throw e;
			}
		}
	}
	
	@Override
	public T getModel() {
		return entity;
	}

	/**
	 * @return the entity
	 */
	public T getEntity() {
		return entity;
	}

	/**
	 * @param entity
	 * the entity to set
	 */
	public void setEntity(T entity) {
		this.entity = entity;
	}

}
